import calculateExpression from "../../../expression/arithmetic.js"; //规则和计算
import { reloadField, updateField } from "../context/metadata-context.js";
import eventBus from "../eventBus/index.js";
import { fieldFilterNormal } from "../utils/filter.js";
import { v4 as uuid } from "uuid";
//规则依赖的接口
let convert = calculateExpression.converter;
let parser = calculateExpression.parser;
let calculator = calculateExpression.calculator();

//设置规则计算
//根据字段的隐藏规则公式，返回true/false
export default function (options) {
  var rules = options.rules; //当前字段的规则
  var form_rules = options.form_rules; //当前表单的所有规则
  var formula;
  if (rules.rules && rules.rules.length) {
    formula = rules.rules.join(" " + rules.symbol + " "); //如果有多个规则，用symbol拼接，比如 "规则1 and 规则2"
  } else {
    formula = rules;
  }

  var buobj = {
    tb_code: options.tb_code, //所在分组code 主表为main
    type: options.type, //初始化计算为 init
  };
  var ff_data = options.form_data; //表单数据
  var ori_expression = convert.ruleToExpression(form_rules, formula, ff_data, buobj); //1.根据规则获得字段字符串 "eq([main.tiaojian1],'1')"
  var rst_expression = ""; //2.根据字段转换成实际的字段公式 "eq(1,'1')"
  var containSub = calculateExpression.isExpressionContainSubTable(ori_expression);

  if (containSub) {
    //条件包含子表字段
    var calculator_inline = {
      table_code: options.tb_code,
      row_i: options.row_i,
    };
    rst_expression = parser.parse(ori_expression, ff_data, calculator_inline);
  } else {
    //条件只包含主表字段
    rst_expression = parser.parse(ori_expression, ff_data);
  }

  calculator.calculateAsync(rst_expression, function (rst_value) {
    //3.根据公式串转换为true/false
    if ((typeof rst_value === "number" && isNaN(rst_value)) || (typeof rst_value === "string" && rst_value === "NaN")) {
      rst_value = false;
    }
    options.callBack(rst_value); //执行规则回调
  });
}

//子表行规则应用
//group: 子表Group对象
//rowIndex: 子表行号
export function triggerGroupRowRule(group, rowIndex, data_define) {
  let currentDefine;
  if (data_define?.children) {
    currentDefine = data_define?.children?.find((g) => g.code === group.code);
  }

  group.fields.filter(fieldFilterNormal)?.forEach((field) => {
    // //触发隐藏规则
    let rules = field.designProps?.rules;
    if (rules) {
      rules?.hidden?.rules?.forEach((rule) => {
        eventBus.publish(`rule.${rule}`);
        eventBus.publish(`rule.${rule}`, rowIndex);
      });

      //触发必填规则
      rules?.required?.rules?.forEach((rule) => {
        eventBus.publish(`rule.${rule}`);
        eventBus.publish(`rule.${rule}`, rowIndex);
      });

      //触发样式规则
      let contentStyles = rules.style?.filter((s) => s.target === "content") || [];
      contentStyles?.forEach((contentStyle) => {
        eventBus.publish(`rule.${contentStyle.id}`);
        eventBus.publish(`rule.${contentStyle.id}`, rowIndex);
      });
      //触发超链接隐藏规则
      let linkHideRules = rules.hiddenLink;
      linkHideRules?.forEach((contentStyle) => {
        eventBus.publish(`rule.${contentStyle.id}`);
        eventBus.publish(`rule.${contentStyle.id}`, rowIndex);
      });
    }

    if (currentDefine == undefined) {
      eventBus.publish("field.blur", `form.form_data.children.${group.code}[${rowIndex}].${field.code}`, undefined, rowIndex);
    }
  });

  //触发新增行的计算字段
  if (currentDefine) {
    eventBus.publish("group.row.triggerCalculate." + group.code, rowIndex);
  }
}

//删除子表当rowIndex行的所有数据
export function deleteGroupRow(group, data, rowIndex) {
  data?.splice(rowIndex, 1);
  group.fields.forEach((field) => {
    if (field.isHiddenRows && field.isHiddenRows.length > 0) {
      field.isHiddenRows.splice(rowIndex, 1);
    }
    if (field.isRequiredRows && field.isRequiredRows.length > 0) {
      field.isRequiredRows.splice(rowIndex, 1);
    }
    if (field.contentStyles && field.contentStyles.length > 0) {
      field.contentStyles.splice(rowIndex, 1);
    }
  });
}

//更新当前group子表验证规则
export function revalidateSubGroup(metadataManager, groupCode) {
  metadataManager.validationLocker = true;
  metadataManager.clearError(["form.form_data.children." + groupCode]);
  eventBus.publish(`group.update.${groupCode}`);
  setTimeout(() => {
    delete metadataManager.validationLocker;
  }, 0);
}

//新增行触发sql模式计算
export function triggerSqlAPIValueCaculate(form, group, rowIndex) {
  let triggers = form.data.form.triggers;
  let set = new Set();
  Object.keys(triggers).forEach((key) => {
    (triggers[key] || []).forEach((field = "") => {
      if (field.startsWith(group.code + ".")) {
        set.add(field);
      }
    });
  });

  if ([...set].length > 0) {
    //如果当前子表在trigger内存在依赖，则发送一次请求进行更新
    eventBus.publish("group.row.add", [...set], group.code, rowIndex);
  }
}

//表单数据更新
export function formReload(form, data) {
  const tplData = form.data;

  //1.附件更新
  if (data.attachments) {
    var json = data.file_control.concat(tplData.form.file_control);
    var newJson = []; //盛放去重后数据的新数组
    for (var k = 0; k < json.length; k++) {
      //循环json数组对象的内容
      var flag = true; //建立标记，判断数据是否重复，true为不重复
      for (var j = 0; j < newJson.length; j++) {
        //循环新数组的内容
        if (json[k].id == newJson[j].id) {
          //让json数组对象的内容与新数组的内容作比较，相同的话，改变标记为false
          flag = false;
        }
      }
      if (flag) {
        //判断是否重复
        newJson.push(json[k]); //不重复的放入新数组。 新数组的内容会继续进行上边的循环。
      }
    }
    tplData.form.file_control = newJson; //1.更新附件权限
    tplData.form.form_data.attachments = data.attachments; //2.更新所有附件 不包含附件步骤权限
    tplData.form.form_data.attachmentTypes = data.attachmentTypes; //3.更新附件分类

    for (var key in tplData.form.form_data.attachments) {
      var fileCtl = "";
      var fitle = tplData.form.form_data.attachments[key];
      fitle.is_delete = true;
      fitle.is_download = true;
      for (var i = 0; i < tplData.form.file_control.length; i++) {
        if (tplData.form.file_control[i].id == tplData.form.form_data.attachments[key].id) {
          fileCtl = tplData.form.file_control[i];
          fitle.is_delete = fileCtl.is_delete;
          fitle.is_download = fileCtl.is_download;
        }
      }
    }
  }

  //2.相关流程更新
  if (data.relation_process.length != 0) {
    eventBus.publish("relationProcessList.update", data.relation_process);
  }

  //主表reload定义
  const main_data = data.main || {};
  //子表reload定义集合
  const children_data = data.children || {};

  var flowStatus = tplData.__flowStatus__; //当前流程状态
  var status = ["start", "restart", "draft"]; //发起 重新发起 草稿
  //3.更新主表
  for (var key in main_data) {
    tplData.form.form_data.main[key] = main_data[key];
    eventBus.publish(updateField + `form.form_data.main.${key}`, main_data[key]); //更新tplData数据和字段UI
    // if (!~status.indexOf(flowStatus)) {
      eventBus.publish("field.blur", `form.form_data.main.${key}`, main_data[key]);
    // }
    // eventBus.publish(reloadField, `form.form_data.main.${key}`, main_data[key]);
  }
  //4.更新子表
  for (var key in children_data) {
    //子表的数据
    let dataList = tplData.form.form_data?.children?.[key];
    //子表的定义
    let group = tplData.form.form_meta_data.groups?.find((g) => g.code === key);
    if (group === undefined) {
      return;
    }
    //子表reload定义
    let theChildren = children_data[key];
    for (var i = 0; i < theChildren.length; i++) {
      //子表reload定义项
      var item = theChildren[i];
      //更新操作
      if (item.status == "update") {
        dataList.forEach((row, rowIndex) => {
          //找到obj_id对应的行数据进行更新
          if (row["obj_id"] == item["obj_id"]) {
            for (var key in item.field) {
              if (typeof row[key] != "undefined") {
                row[key] = item.field[key];

                //流程状态不是 发起 重新发起 草稿   这种场景需要触发计算字段
                // if (!~status.indexOf(flowStatus)) {
                  let fullFieldPath = "form.form_data.children." + group.code + "[" + rowIndex + "]." + key; //更新tpldata需要的完整路径
                  eventBus.publish("field.blur", fullFieldPath, row[key], rowIndex);
                // }
              }
            }
          }
        });
      }
      //删除操作
      else if (item.status == "del") {
        for (let ir = 0; ir < dataList.length; ir++) {
          var row = dataList[ir];
          //找到obj_id对应的行数据进行删除
          if (row["obj_id"] == item["obj_id"]) {
            //删除子表当前行的所有数据
            deleteGroupRow(group, dataList, ir);
            //删除数组元素时，数组长度会变化，是一个全新数组，使 ir=-1 归零重新循环新数组
            ir = -1;
          }
        }
      }
      //新增操作
      else if (item.status == "add") {
        let addedRow = { __cid__: uuid() };
        //从子表定于里面的字段进行对比并赋值
        for (var icol = 0; icol < group.fields.length; icol++) {
          var col = group.fields[icol];
          var fdCode = col.code;
          //这是用来过滤脏数据的吗？
          if (fdCode == "obj_id") continue;
          addedRow[fdCode] = typeof item.field[fdCode] != "undefined" ? item.field[fdCode] : null;
        }
        //新增的行需要obj_id,从业务系统带过来的
        addedRow["obj_id"] = item["obj_id"];
        dataList.push(addedRow);
        //触发规则
        triggerGroupRowRule(group, dataList.length - 1, tplData.form.data_define);
        //新增行触发sql模式计算
        triggerSqlAPIValueCaculate(form, group, dataList.length - 1);
      }
    }

    //5.更新校验
    revalidateSubGroup(form, key);
  }
}
